home *** CD-ROM | disk | FTP | other *** search
/ ftp.mactech.com 2010 / ftp.mactech.com.tar / ftp.mactech.com / machack / Hacks96 / FlyPaper.sit / Fly Paper / FlyPaper Source / App Sources / Clippings.cpp next >
Text File  |  1996-06-22  |  12KB  |  480 lines

  1. #if 0
  2.  
  3. #include "ST_MacClasses.h"
  4.  
  5. #ifndef CLIPPINGS_H
  6. #include "Clippings.h"
  7. #endif
  8.  
  9. #ifndef FLYPAPERUTILS_H
  10. #include "FlyPaperUtils.h"
  11. #endif
  12.  
  13. #ifndef FLYPAPERAPP_H
  14. #include "FlyPaperApp.h"
  15. #endif
  16.  
  17. #ifndef FLYPAPERDRAGUTILS_H
  18. #include "FlyPaperDragUtils.h"
  19. #endif
  20.  
  21. #ifndef CLIPPINGFILE_H
  22. #include "ClippingFile.h"
  23. #endif
  24.  
  25. #ifndef THUMBNAIL_H
  26. #include "Thumbnail.h"
  27. #endif
  28.  
  29. #include <drag.h>
  30. #include <Devices.h>
  31. #include <Folders.h>
  32. #include <TextUtils.h>
  33. #include <Fonts.h>
  34. #include "floaters.h"
  35.  
  36. extern GlobalsRec                glob;
  37.  
  38. #define    kWatchFolderDelay        60
  39.  
  40. WindowPtr    gWindowBeingDragged = nil;
  41. Point        gClickPoint;
  42.  
  43. WindowPtr    CreateClippingWindow (ClippingID id, Rect& bounds, Boolean onLeft);
  44.  
  45. typedef struct {
  46.     ClippingID            clippingID;
  47.     Rect                windowBounds;
  48.     WindowPtr            window;
  49.     CThumbnail*            thumbnail;
  50.     Boolean                onLeft;
  51. } ClippingRec;
  52.  
  53. typedef struct {
  54.     short                numClippings;
  55.     unsigned long        clippingsFolderDate;
  56.     short                update;
  57.     ClippingRec            clippings [];
  58. } ClippingsListHeader, **ClippingListHandle;
  59.  
  60. ClippingListHandle        gClippingsList = nil;
  61.  
  62. Boolean InitClippings ()
  63. {
  64.     OSErr                error;
  65.     
  66.     gClippingsList = (ClippingListHandle) TempNewHandle (sizeof (ClippingsListHeader), &error);
  67.     if (!gClippingsList)
  68.         return false;
  69.     
  70.     (**gClippingsList).numClippings = 0;
  71.     (**gClippingsList).update = 0;
  72.     (**gClippingsList).clippingsFolderDate = 1;        // even less likely than 12:00am Jan 1, 1904
  73.     
  74.     return true;
  75. }
  76.  
  77. static
  78. void    CalcWindowPosition (Point dropPoint, Rect& bounds, short tile, Boolean &onLeft)
  79. {    
  80.     #define        kClippingWidth        110
  81.     
  82.     Rect                    globalRect = (**GetGrayRgn ()).rgnBBox;
  83.     
  84.     OffsetRect (&bounds, 0, dropPoint.v + tile * 20);
  85.     if (globalRect.right - dropPoint.h < dropPoint.h - globalRect.left) {
  86.         onLeft = true;
  87.         OffsetRect (&bounds, globalRect.right - bounds.right - bounds.left, 0);
  88.     } else {
  89.         onLeft = false;
  90.         OffsetRect (&bounds, globalRect.left, 0);
  91.     }
  92. }
  93.  
  94. static
  95. short    FindClipping (ClippingID id, ClippingRec& clipping)
  96. {
  97.     for (short whichClipping = 0; whichClipping < (**gClippingsList).numClippings; ++whichClipping) {
  98.         if ((**gClippingsList).clippings [whichClipping].clippingID == id) {
  99.             clipping = (**gClippingsList).clippings [whichClipping];
  100.             return whichClipping;
  101.         }
  102.     }
  103.     return -1;
  104. }
  105.  
  106. static
  107. void    DeleteClipping (ClippingID id)
  108. {
  109.     for (short whichClipping = 0; whichClipping < (**gClippingsList).numClippings; ++whichClipping) {
  110.         if ((**gClippingsList).clippings [whichClipping].clippingID == id) {
  111.  
  112.             delete (**gClippingsList).clippings [whichClipping].thumbnail;
  113.             
  114.             BlockMoveData (    &(**gClippingsList).clippings [whichClipping + 1],
  115.                             &(**gClippingsList).clippings [whichClipping],
  116.                             sizeof (ClippingRec) * ((**gClippingsList).numClippings - whichClipping - 1));
  117.             SetHandleSize ((Handle) gClippingsList,
  118.                     GetHandleSize ((Handle) gClippingsList) - sizeof (ClippingRec));
  119.             --(**gClippingsList).numClippings;
  120.             return;
  121.         }
  122.     }
  123. }
  124.  
  125. static
  126. void AppendClipping (ClippingRec& clipping)
  127. {
  128.     if (PtrAndHand (&clipping, (Handle) gClippingsList, sizeof (ClippingRec)))
  129.         return;
  130.     else {
  131.         ++(**gClippingsList).update;
  132.         ++(**gClippingsList).numClippings;
  133.     }
  134. }
  135.  
  136. void ProcessPendingClippings (void)
  137. {
  138.     if ((**gClippingsList).update == 0)
  139.         return;
  140.     
  141.     for (short whichClipping = 0; (**gClippingsList).update && (whichClipping < (**gClippingsList).numClippings); ++whichClipping) {
  142.         if ((**gClippingsList).clippings [whichClipping].window == nil) {
  143.             // create clipping window here
  144.             Rect        bounds = (**gClippingsList).clippings [whichClipping].windowBounds;
  145.             Boolean        onLeft = (**gClippingsList).clippings [whichClipping].onLeft;
  146.             ClippingID    id = (**gClippingsList).clippings [whichClipping].clippingID;
  147.             (**gClippingsList).clippings [whichClipping].window =
  148.                     CreateClippingWindow (id, bounds, onLeft);
  149.             --(**gClippingsList).update;
  150.         }
  151.     }
  152. }
  153.  
  154. void CheckForNewClippings (void)
  155. {
  156.     static unsigned long    nextCheck = 0;
  157.     CInfoPBRec                pb;
  158.     Str255                    name;
  159.     long                    dirID;
  160.     
  161.     if (TickCount () < nextCheck)
  162.         return;
  163.     
  164.     nextCheck = TickCount () + kWatchFolderDelay;
  165.     
  166.     OSErr                    error = FlyPaperFindFolder (kOnSystemDisk, kClippingsFolder, true, &pb.hFileInfo.ioVRefNum,
  167.                                 &dirID);
  168.     if (error)
  169.         return;
  170.     
  171.     pb.hFileInfo.ioNamePtr = name;
  172.     pb.hFileInfo.ioFDirIndex = -1;
  173.     pb.hFileInfo.ioDirID = dirID;
  174.     error = PBGetCatInfoSync (&pb);
  175.     if (error)
  176.         return;
  177.     
  178.     if (pb.dirInfo.ioDrMdDat != (**gClippingsList).clippingsFolderDate) {
  179.         (**gClippingsList).clippingsFolderDate = pb.dirInfo.ioDrMdDat;
  180.         for (pb.hFileInfo.ioFDirIndex = 1; ; ++pb.hFileInfo.ioFDirIndex) {
  181.             
  182.             pb.hFileInfo.ioDirID = dirID;
  183.             if (PBGetCatInfoSync (&pb))
  184.                 break;
  185.             
  186.             if (pb.hFileInfo.ioFlFndrInfo.fdType != kClippingFileType)
  187.                 continue;
  188.             
  189.             ClippingID        id;
  190.             ClippingRec        clipping;
  191.             
  192.             StringToNum (name, (long*) &id);
  193.             
  194.             short            index = FindClipping (id, clipping);
  195.             if (index < 0) {
  196.                 FlyPaperAuxDataHandle        auxData;
  197.                 
  198.                 if (GetClippingFileAuxData (id, auxData))
  199.                     return;
  200.                     
  201.                 clipping.clippingID = id;
  202.                 clipping.thumbnail = CThumbnail::NewThumbnail (id);
  203.                 if (clipping.thumbnail)
  204.                     clipping.thumbnail -> GetWindowBounds (clipping.windowBounds);
  205.                 else
  206.                     SetRect (&clipping.windowBounds, 0, 0, 40, 20);
  207.                 CalcWindowPosition ((**auxData).dropSpot, clipping.windowBounds, 0, clipping.onLeft);
  208.                 clipping.window = nil;
  209.                 DisposeHandle ((Handle) auxData);
  210.                 AppendClipping (clipping);
  211.             }
  212.         }
  213.     }
  214. }
  215.  
  216. static
  217. Boolean RememberDragItem (DragReference dragRef, ItemReference dragItem, ClippingID& clippingID, Point dropSpot)
  218. {
  219.     short                        clippingResFile = -1;
  220.     FlyPaperAuxDataHandle        auxData;
  221.     unsigned short                numFlavors;
  222.     
  223.     if (CountDragItemFlavors (dragRef, dragItem, &numFlavors))
  224.         return false;
  225.         
  226.     for (unsigned short whichFlavor = 1; whichFlavor <= numFlavors; ++whichFlavor) {
  227.                             
  228.         if (AcceptableFlavor (dragRef, dragItem, whichFlavor)) {
  229.             FlavorType        type;
  230.             FlavorFlags        flags;
  231.             Size            size;
  232.  
  233.             if (GetFlavorType (dragRef, dragItem, whichFlavor, &type))
  234.                 return false;
  235.             if (GetFlavorFlags (dragRef, dragItem, type, &flags))
  236.                 return false;
  237.  
  238.             if (clippingResFile == -1) {
  239.                 if (CreateClippingFile (&clippingResFile, kClippingFileType, auxData, clippingID))
  240.                     return false;    
  241.                 (**auxData).dropSpot = dropSpot;
  242.             }
  243.             
  244.             ST_ResFileCloser        clippingResFileCloser (clippingResFile);
  245.             
  246.             Handle        dataHandle = NULL;
  247.             
  248.             if (GetFlavorDataSize (dragRef, dragItem, type, &size)) {
  249.                 continue;
  250.             }
  251.             
  252.             /* allocate memory for the drag item */
  253.             Handle            data = NewHandle (size);
  254.             if (!data) {
  255.                 OSErr    error;
  256.                 data = TempNewHandle (size, &error);
  257.                 if (!data)
  258.                     continue;
  259.             }
  260.  
  261.             ST_Handle                    dataKiller (dataHandle);
  262.             {
  263.                 ST_HandleStateSaver     dataStateSaver (data);
  264.                 
  265.                 HLock (data);
  266.                 if (GetFlavorData (dragRef, dragItem, type, *data, &size, 0))
  267.                     continue;
  268.             }
  269.                                         
  270.             if (AddFlavorToClippingFile (clippingResFile, type, data))
  271.                 continue;
  272.             
  273.             WriteResource (data);
  274.             ReleaseResource (data);
  275.             dataKiller.Forget ();
  276.             clippingResFileCloser.Forget ();
  277.         }
  278.     }
  279.     
  280.     if (clippingResFile != -1) {
  281.         CloseResFile (clippingResFile);
  282.         return true;
  283.     } else
  284.         return false;
  285. }
  286.  
  287. void AcceptNewClipping (DragReference dragRef, Point dropLocation)
  288. {    
  289.     unsigned short            numItems;
  290.     Boolean                    newClippingMade = false;
  291.     short                    tileCount = 0;
  292.     
  293.     if (CountDragItems (dragRef, &numItems))
  294.         return;
  295.         
  296.     for (unsigned short whichItem = 1; whichItem <= numItems; ++whichItem) {
  297.         ClippingID                clippingID;
  298.         ItemReference            dragItem;
  299.         
  300.         if (GetDragItemReferenceNumber (dragRef, whichItem, &dragItem))
  301.             return;
  302.                 
  303.         if (RememberDragItem (dragRef, dragItem, clippingID, dropLocation)) {
  304.             newClippingMade = true;
  305.         }
  306.     }
  307.  
  308.     if (newClippingMade)
  309.         WakeUpProcess(&glob.myPSN);
  310. }
  311.  
  312. static
  313. void DiscardClippingWindow (WindowPtr win)
  314. {
  315.     ClippingID            id = GetWRefCon (win);
  316.     
  317.     if (id && DeleteClippingFile (id) == noErr) {
  318.         DeleteClipping (id);
  319.         DisposeFloater (win);
  320.     } else
  321.         DisposeFloater (win);
  322. }
  323.  
  324. static
  325. void ClippingDisposeProc (WindowPtr win)
  326. {
  327.     ClippingID            id = GetWRefCon (win);
  328.     
  329.     if (id)
  330.         DeleteClipping (id);
  331.     DisposeFloater (win);
  332. }
  333.  
  334. static void MySetCursor (Cursor* cursor)
  335. {
  336.     // Call SetCursor directly through jSetCursor, since someone's stupid patch does not allow
  337.     // SetCursor to operate properly.  :-(
  338.     // Wish I knew why I was passing in 16, but the ROM does it.  When in ROMe...
  339.     
  340.     typedef pascal void (*jSetCrsrProc) (Point, short, void*, void*);    
  341.     (*((jSetCrsrProc*) 0x00000818)) (cursor -> hotSpot, 16, &cursor -> data, &cursor -> mask);
  342. }
  343.  
  344. static
  345. void ClippingWindowMouseDown (WindowPtr win, EventRecord *theEvent)
  346. {
  347.     GrafPtr        oldPort;
  348.     GetPort (&oldPort);
  349.     SetPort (win);
  350.     gClickPoint = theEvent -> where;
  351.     GlobalToLocal (&gClickPoint);
  352.     SetPort (oldPort);
  353.     
  354.     if (WaitMouseMoved (theEvent -> where)) {
  355.         ClippingID                id = GetWRefCon (win);
  356.         ClippingRec                clipping;
  357.         short                    whichClipping = FindClipping (id, clipping);
  358.         Boolean                    draggedToSelf = false;
  359.         
  360.         if (whichClipping >= 0) {
  361.             DragReference            dragRef;
  362.             OSErr                    error = ClippingFileToDragReference (id, dragRef, true);
  363.             
  364.             if (error == noErr) {
  365.                 RgnHandle                rgn1 = NewRgn ();
  366.                 RgnHandle                rgn2 = NewRgn ();
  367.                 
  368.                 CopyRgn (((WindowPeek)win) -> contRgn, rgn1);
  369.                 
  370.                 CopyRgn (rgn1, rgn2);
  371.                 InsetRgn (rgn2, 1, 1);
  372.                 
  373.                 DiffRgn (rgn1, rgn2, rgn1);
  374.                                 
  375.                 gWindowBeingDragged = win;
  376.                 MySetCursor (&qd.arrow);
  377.                 error = TrackDrag (dragRef, theEvent, rgn1);
  378.                 if (gWindowBeingDragged == nil)
  379.                     draggedToSelf = true;
  380.                 else
  381.                     draggedToSelf = false;
  382.                 gWindowBeingDragged = nil;
  383.                 
  384.                 DisposeRgn (rgn1);
  385.                 DisposeRgn (rgn2);
  386.                 DisposeDrag (dragRef);
  387.                 
  388.                 if (error == noErr && ((theEvent -> modifiers & optionKey) == 0) &&
  389.                         !OptionKeyDown () && !draggedToSelf) {
  390.                     DiscardClippingWindow (win);
  391.                 }
  392.             }
  393.         }
  394.     }
  395. }
  396.  
  397. static
  398. void ClippingEventHandler (EventRecord *theEvent, WindowPtr win)
  399. {
  400.     switch (theEvent -> what) {
  401.     
  402.         case updateEvt :
  403.             GrafPtr            oldPort;
  404.             long            refCon;
  405.             ClippingRec        clipping;
  406.             
  407.             GetPort (&oldPort);
  408.             SetPort (win);
  409.             Rect    r = win -> portRect;
  410.             InsetRect (&r, 6, 2);
  411.             
  412.             BeginUpdate (win);
  413.             EraseRect (&win -> portRect);
  414.             if (FindClipping (GetWRefCon (win), clipping) >= 0) {
  415.                 if (clipping.thumbnail)
  416.                     clipping.thumbnail -> Draw (r);
  417.             }
  418.             EndUpdate (win);
  419.             break;
  420.         
  421.         case mouseDown :
  422.             short        partCode = theEvent -> message;
  423.             switch (partCode) {
  424.                 case inContent :
  425.                     ClippingWindowMouseDown (win, theEvent);
  426.                     break;
  427.                 
  428.                 case inDrag :
  429.                     break;
  430.             }
  431.             break;
  432.         
  433.         case keyDown :
  434.         case autoKey :
  435.             break;
  436.     
  437.     }
  438. }
  439.  
  440. WindowPtr    CreateClippingWindow (ClippingID id, Rect& bounds, Boolean onLeft)
  441. {
  442.     GrafPtr        oldPort;
  443.     
  444.     Handle        wctb = GetResource ('wctb', 128 + (Random () & 0x7FFF) % 6);
  445.     
  446.     WindowPtr    win = NewFloater (nil, &bounds, "\p", true, onLeft ? kLeftWindowProc : kRightWindowProc, (WindowPtr) -1,
  447.                     false, id, 0, ClippingEventHandler, ClippingDisposeProc);
  448.     if (!win)
  449.         return nil;
  450.     if (wctb)
  451.         SetWinColor (win, (WinCTab**)wctb);
  452.     
  453.     ShowWindow (win);
  454.     UpdateFloater (win);
  455.         
  456.     return win;
  457. }
  458.  
  459. #if 0
  460.  
  461. void RepositionClipping (DragReference drag, WindowPtr w)
  462. {
  463.     Point        mouse, pinnedMouse;
  464.     OSErr        error = GetDragMouse (drag, &mouse, &pinnedMouse);    
  465.  
  466.     if (!error) {
  467.         mouse.h -= gClickPoint.h;
  468.         mouse.v -= gClickPoint.v;
  469.         
  470.         Boolean        onLeft;
  471.         Rect        bounds = w -> portRect;
  472.         CalcWindowPosition (mouse, bounds, 0, onLeft);
  473.         
  474.         MoveWindow (w, bounds.left, bounds.top, false);
  475.     }
  476. }
  477.  
  478. #endif
  479.  
  480. #endif